﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SBlogCore.Common.FriendlyException;
using SBlogCore.Common.Models;
using SBlogCore.Common.Utilities.Extension;

namespace SBlogCore.Common.Filters
{
    [SkipScan]
    public class GlobalExceptionFilter : IAsyncExceptionFilter ,IOrderedFilter
    {
        /// <summary>
        /// 过滤器排序
        /// </summary>
        internal const int FilterOrder = 9998;

        /// <summary>
        /// 排序属性
        /// </summary>
        public int Order => FilterOrder;
        private readonly IWebHostEnvironment _env;
        private readonly ILogger<GlobalExceptionFilter> _logger;

        public GlobalExceptionFilter(
            IWebHostEnvironment env,
            ILogger<GlobalExceptionFilter> logger)
        {
            this._env = env;
            this._logger = logger;
        }

        public Task OnExceptionAsync(ExceptionContext context)
        {
            var _expection = context.Exception;
            ResultEntity<object?> result = new ResultEntity<object?>();
            if (_expection is AppFriendlyException)
            {
                result = ResultEntity<object?>.Error(_expection.Message);
            }
            else
            {
                result.message = _expection.Message;
                result.status = 500;
                var errorAudit = "Unable to resolve service for";
                if (!string.IsNullOrEmpty(result.message) && result.message.Contains(errorAudit))
                {
                    result.message = result.message.Replace(errorAudit, $"（确保服务接口是否引用！\n 服务是否被注册！\n 若新添加服务，需要重新编译项目！ \n ）{errorAudit}");
                }
                if (_env.EnvironmentName.ObjToString().Equals("Development"))
                {
                    result.msgDev = context.Exception.StackTrace!;//堆栈信息
                }
                _logger.LogError(result.message + WriteLog(result.message, context.Exception));
            }
            context.Result = new JsonResult(result);
            return Task.CompletedTask;//获取一个成功完成的任务
        }
        /// <summary>
        /// 自定义返回格式
        /// </summary>
        /// <param name="throwMsg"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        private string WriteLog(string throwMsg, Exception ex)
        {
            return string.Format("\r\n【自定义错误】：{0} \r\n【异常类型】：{1} \r\n【异常信息】：{2} \r\n【堆栈调用】：{3}", new object[] { throwMsg,
                ex.GetType().Name, ex.Message, ex.StackTrace });
        }
    }
}
